Bugsnag ने हाल ही में मिनीडंप को संसाधित करने के लिए समर्थन जोड़ा है ताकि ग्राहक इलेक्ट्रॉन पर मूल क्रैश या ब्रेकपैड या क्रैशपैड का उपयोग करते समय उत्पन्न क्रैश को ट्रैक कर सकें।
मिनीडम्प समर्थन को जोड़ने से कई तकनीकी चुनौतियों का सामना करना पड़ा, जिन्हें हमें यह सुनिश्चित करने के लिए संबोधित करना था कि हम अपने सामान्य त्रुटि घटना प्रसंस्करण थ्रूपुट को प्रभावित किए बिना फाइलों को एक कुशल, स्केलेबल तरीके से संसाधित कर सकते हैं।
मिनीडम्प एक फ़ाइल है जो क्रैश होने पर कुछ प्रक्रियाओं द्वारा उत्पन्न होती है। वे कोर डंप से छोटे होते हैं और बुनियादी डिबगिंग संचालन करने के लिए आवश्यक डेटा प्रदान करते हैं।
मिनीडम्प फ़ाइल स्वरूप का आविष्कार विंडोज़ में उपयोग के लिए किया गया था जब ओएस एक अप्रत्याशित त्रुटि का सामना करता है। इसके बाद, Google के ब्रेकपैड और क्रैशपैड जैसे टूल ने कई प्लेटफार्मों पर एप्लिकेशन क्रैश डंप उत्पन्न करने के लिए एक ही प्रारूप को अपनाया। इलेक्ट्रॉन के साथ निर्मित ऐप्स भी देशी क्रैश के लिए मिनीडम्प फ़ाइलें उत्पन्न करते हैं (चूंकि इलेक्ट्रॉन क्रैशपैड का उपयोग करता है)।
मिनीडम्प फ़ाइल में क्रैश के समय की प्रक्रिया के बारे में जानकारी होती है और इसमें विवरण शामिल होते हैं जैसे:
मिनीडम्प के भीतर प्रत्येक सक्रिय थ्रेड का रनटाइम स्टैक होता है (जिस समय त्रुटि हुई थी) और उन थ्रेड्स के लिए रजिस्टर मान।
इन विवरणों का उपयोग स्टैक पर चलने और प्रत्येक थ्रेड के लिए स्टैक ट्रेस बनाने के लिए किया जा सकता है। कुछ मामलों में अकेले इस पद्धति का उपयोग करके एक वैध (हालांकि असंबद्ध) स्टैक ट्रेस प्राप्त करना संभव है, लेकिन अन्य मामलों में हमें अतिरिक्त कॉल फ़्रेम सूचना (सीएफआई) की आवश्यकता होती है जो डीबग फ़ाइलों के भीतर प्रदान की जाती है।
कॉल फ़्रेम सूचना (सीएफआई) रिकॉर्ड बताते हैं कि किसी विशेष मशीन पते पर रजिस्टर मूल्यों को कैसे पुनर्स्थापित किया जाए। यह डेटा आम तौर पर डिबग फ़ाइलों में प्रदान किया जाता है और स्टैक पर चलते समय अधिक विश्वसनीय स्टैक ट्रेस उत्पन्न करने की अनुमति देता है।
सीएफआई जानकारी के बिना स्टैक वॉकर को कॉलिंग फ्रेम को खोजने का प्रयास करने के लिए स्टैक को स्कैन करने की आवश्यकता हो सकती है लेकिन यह कम विश्वसनीय हो सकता है और अमान्य स्टैक ट्रेस उत्पन्न कर सकता है।
एक बार स्टैक ट्रेस प्राप्त हो जाने के बाद इसमें केवल प्रत्येक फ्रेम के पते होंगे। एक सार्थक स्टैक ट्रेस (फ़ंक्शन नाम, स्रोत फ़ाइल, और प्रत्येक फ़्रेम के लिए स्रोत लाइन नंबर के साथ) का उत्पादन करने के लिए हमें इसे "प्रतीकात्मक" करने की आवश्यकता है, अर्थात उन पर डिबग प्रतीकों को लागू करें।
इसके लिए कंपाइलर से संबंधित डिबग फ़ाइल (जैसे macOS के लिए dSYM) का उपयोग किया जा सकता है, लेकिन ब्रेकपैड ने अपने स्वयं के प्रतीक फ़ाइल प्रारूप को परिभाषित किया है जिसका उपयोग इसके बजाय किया जा सकता है।
ब्रेकपैड प्रतीक फ़ाइल अधिकांश कंपाइलर-जनरेटेड डिबग फ़ाइलों की तुलना में सरल है (इसमें सार सिंटैक्स ट्री जैसे विवरण शामिल नहीं हैं) लेकिन स्टैक ट्रेस को दर्शाने के लिए एक पठनीय प्रारूप में आवश्यक विवरण प्रदान करता है।
ब्रेकपैड मिनीडंप को मैन्युअल रूप से संसाधित करने या प्रसंस्करण के लिए एक समर्पित सर्वर/सेवा पर अपलोड करने में सहायता के लिए कई टूल प्रदान करता है:
minidump_stackwalk एक मिनीडम्प फ़ाइल और वैकल्पिक ब्रेकपैड प्रतीक फ़ाइलें लेता है और अन्य जानकारी के साथ प्रत्येक थ्रेड के लिए स्टैक ट्रेस को आउटपुट करता है (जैसे क्रैश का कारण, प्रत्येक फ़्रेम के लिए मान पंजीकृत करना, ऑपरेटिंग सिस्टम का विवरण, आदि)। यह मिनीडंप को पार्स करने और उनसे सार्थक स्टैक ट्रेस प्राप्त करने के लिए एक उपयोगी उपकरण है।
minidump_dump मिनीडंप के बारे में अधिक विस्तृत जानकारी प्रदान करता है (जैसे कि मिनीडंप के भीतर प्रत्येक स्ट्रीम का विवरण)।
minidump_upload प्रसंस्करण के लिए एक समर्पित सर्वर (जैसे Bugsnag) पर minidump फ़ाइलें अपलोड करता है।
डंप_सिम्स एप्लिकेशन बाइनरी और डिबग फाइलों से ब्रेकपैड सिंबल फाइल जेनरेट करता है।
symupload प्रसंस्करण के लिए एक समर्पित सर्वर पर ब्रेकपैड प्रतीक फ़ाइलें अपलोड करता है (जैसे Bugsnag)।
प्रासंगिक प्रतीक फ़ाइलों के साथ minidump_stackwalk टूल के आउटपुट का एक उदाहरण नीचे देखा जा सकता है:
-- कोड भाषा-सादा पाठ -- ऑपरेटिंग सिस्टम: Windows NT 10.0.19041 1151CPU: amd64 परिवार 23 मॉडल 24 चरण 1 8 CPU
जीपीयू: अज्ञात
क्रैश का कारण: बिना क्रिया के C++ अपवाद क्रैश पता: 0x7ff887f54ed9 प्रक्रिया अपटाइम: 4 सेकंड
थ्रेड 0 (दुर्घटनाग्रस्त) 0 KERNELBASE.dll + 0x34ed9
rax = 0x655c67616e736775 rdx = 0x6f6d2d6576697461 rcx = 0x6e2d7070635c656d rbx = 0x00007ff87f731600 rsi = 0x000000b80f3fcb70 rdi = 0x000000b80f3fca40 rbp = 0x000000b80f3fca10 rsp = 0x000000b80f3fc8d0 r8 = 0xaaaaaaaa0065646f r9 = 0xaaaaaaaaaaaaaaaa r10 = 0xaaaaaaaaaaaaaaaa r11 = 0xaaaaaaaaaaaaaaaa r12 = 0x00007ff87f6f1ba0 r13 = 0x000010ff084af60d r14 = 0xffffffff00000000 r15 = 0x0000000000000420 rip = 0x00007ff887f54ed9 Found by: given as instruction pointer in context 1 KERNELBASE.dll + 0x34ed9 rbp = 0x000000b80f3fca10 rsp = 0x000000b80f3fc908 rip = 0x00007ff887f54ed9 Found by: stack scanning 2 ntdll.dll + 0x34a5f rbp = 0x000000b80f3fca10 rsp = 0x000000b80f3fc960 rip = 0x00007ff88a6a4a5f Found by: stack scanning 3 my_example.node!CxxThrowException [throw.cpp: 131 + 0x14] rbp = 0x000000b80f3fca10 rsp = 0x000000b80f3fc9b0 rip = 0x00007ff87f6fab75 द्वारा पाया गया: स्टैक स्कैनिंग 4 my_example.node!RunExample(Nan::Function) nfo v8::Value const &) [my_example.cpp: 26 + 0x22] rbp = 0x000000b80f3fca10 rsp = 0x000000b80f3fca20 rip = 0x00007ff87f6f1ec2 द्वारा पाया गया: कॉल फ्रेम जानकारी ..।
Bugsnag में मिनीडंप समर्थन जोड़ते समय हमें कुछ तकनीकी चुनौतियों का सामना करना पड़ा।
मिनीडंप हमारी सामान्य त्रुटि घटना JSON पेलोड से काफी भिन्न होते हैं इसलिए हमें यह सुनिश्चित करना था कि हम उन्हें एक कुशल, लचीला और स्केलेबल तरीके से संसाधित कर सकें।
Minidump फ़ाइलें हमें प्राप्त होने वाले सामान्य पेलोड से बहुत बड़ी हो सकती हैं; हमारे सामान्य पेलोड औसत ~20KB जबकि मिनीडंप आमतौर पर सैकड़ों किलोबाइट आकार के होते हैं। इसके अतिरिक्त, यदि ढेर सारे सक्रिय धागे या बड़े ढेर वाले धागे हैं तो मिनीडंप काफी बड़े (मेगाबाइट के दसियों) प्राप्त कर सकते हैं।
आम तौर पर जब हमें त्रुटि घटना पेलोड प्राप्त होते हैं तो हम उन्हें एसिंक्रोनस प्रोसेसिंग के लिए काफ्का कतार में जोड़ देते हैं ताकि हम अपलोड के साथ किसी भी बैकलॉग को संभालने में सक्षम हों।
हमें यह सुनिश्चित करने की आवश्यकता है कि यदि हम बड़ी मिनीडम्प फ़ाइलों को कतारबद्ध कर रहे हैं तो कतारबद्ध तंत्र विश्वसनीय होगा। मिनीडम्प फ़ाइलें अच्छी तरह से संपीड़ित होती हैं (आमतौर पर उनके मूल आकार के लगभग 10% तक) लेकिन अभी भी एक जोखिम था कि संपीड़ित फ़ाइलें बहुत बड़ी होंगी।
हमने आंतरिक काफ्का उदाहरण पर विभिन्न आकारों के संदेशों के साथ कुछ लोड परीक्षण किया और पाया कि:
डेटा थ्रूपुट और प्रतिकृति अंतराल वास्तव में फ़ाइलों के आकार से प्रभावित नहीं थे।
औसत फ़ाइल आकार में वृद्धि के साथ प्रति सेकंड संसाधित किए जा सकने वाले संदेशों की संख्या कम हो गई।
यह घटी हुई संदेश थ्रूपुट केवल तब महत्वपूर्ण थी जब एक साथ बहुत सारी विशेष रूप से बड़ी फाइलें कतार में थीं लेकिन हम अनुमान लगाते हैं कि ये बहुत दुर्लभ होनी चाहिए और इसलिए काफ्का इस उद्देश्य के लिए उपयुक्त होगा।
ब्रेकपैड के मिनीडम्प_स्टैकवॉक टूल का उपयोग करते हुए मिनीडंप का प्रतीक होने पर ब्रेकपैड प्रतीक फ़ाइलें प्रदान किए जाने पर मिनीडंप को संसाधित करने में बहुत अधिक समय लग सकता है (प्रतीक फ़ाइलों को लोड करने में लगने वाले समय के कारण, उन्हें पार्स करें और प्रासंगिक प्रतीक डेटा देखें)।
एक नमूना इलेक्ट्रॉन मिनीडम्प पर ब्रेकपैड प्रतीक फ़ाइलों के बिना 20ms और उनके साथ 14s लगे!
एक सिंगल मिनीडंप को मैन्युअल रूप से प्रतीकात्मक करते समय धीमा प्रसंस्करण समय बहुत अधिक चिंता का विषय नहीं है, लेकिन हमें यह सुनिश्चित करने की आवश्यकता है कि हम मिनीडंप को यथासंभव कुशलता से संसाधित और प्रतीकात्मक कर सकते हैं ताकि हम मिनीडंप प्रसंस्करण के उच्च थ्रूपुट को बनाए रख सकें।
इसे प्राप्त करने के लिए, हमने अपने स्वयं के प्रतीकात्मक तर्क को लागू किया। ब्रेकपैड प्रतीक फ़ाइल प्रारूप सरल और अच्छी तरह से प्रलेखित है जिसका अर्थ है कि हम एक बीस्पोक मैपिंग फ़ाइल बनाने के लिए फ़ाइल को पार्स कर सकते हैं जो आसान पता देखने की अनुमति देता है।
बीस्पोक फ़ाइल ब्रेकपैड प्रतीक फ़ाइल की तुलना में बहुत बड़ी है, लेकिन लुकअप करने के लिए भी बहुत अधिक कुशल है। ब्रेकपैड प्रतीक फ़ाइल के इस पूर्व-प्रसंस्करण को करने का अर्थ है कि एक मिनीडंप को संसाधित करने में लगने वाला समय काफी कम हो जाता है (प्रतीक फ़ाइलों के लिए बढ़ी हुई भंडारण आवश्यकताओं की कीमत पर)।
मिनीडंप प्रसंस्करण के प्रारंभिक डिजाइन में हमने स्टैक पर चलते समय (दक्षता में सुधार करने के लिए) ब्रेकपैड प्रतीक फ़ाइलों के उपयोग को पूरी तरह से छोड़ दिया था, लेकिन हमें जल्द ही एहसास हुआ कि यह कभी-कभी अनुपलब्ध कॉल फ़्रेम सूचना डेटा के कारण अमान्य स्टैक ट्रेस के परिणामस्वरूप होता है।
हम जानते थे कि यदि हम स्टैक वॉकिंग के लिए पूर्ण ब्रेकपैड प्रतीक फाइलों में पास हुए तो यह धीमा होगा (इस कारण स्टैक ट्रेस को भी प्रतीकात्मक करने की कोशिश कर रहा है) इसलिए इसके बजाय हमने फ़ाइल का एक ट्रिम-डाउन संस्करण तैयार करने का विकल्प चुना जिसमें बस शामिल था स्टैक चलने के लिए आवश्यक जानकारी।
इसने ब्रेकपैड प्रतीक फ़ाइल के आकार के साथ-साथ मिनीडंप को संसाधित करने में लगने वाले समय को बहुत कम कर दिया, लेकिन यह अभी भी बहुत कुशल नहीं था (उदाहरण के लिए इलेक्ट्रॉन मिनीडम्प के लिए 1.5s लेना)।
इसलिए हमने छंटनी की गई ब्रेकपैड प्रतीक फ़ाइल को क्रमबद्ध करने के विकल्प का पता लगाया ताकि इसे अधिक कुशलता से पढ़ा जा सके (बजाय हर बार फ़ाइल को पार्स करने के)। फ़ाइल के क्रमबद्ध संस्करण का उपयोग करने से प्रसंस्करण समय 1.5s से घटाकर 200ms कर दिया गया।
इस प्रदर्शन में सुधार का मतलब है कि हमें सेवा के प्रति उदाहरण मिनीडंप के उच्च थ्रूपुट का समर्थन करने में सक्षम होना चाहिए, जिसका अर्थ है कि हम बुनियादी ढांचे की लागत को कम रख सकते हैं।
जैसे-जैसे नई सुविधा को अपनाना बढ़ता है, हम यह सुनिश्चित करने के लिए अपने बुनियादी ढांचे के उपयोग की बारीकी से निगरानी करेंगे कि हम एक कुशल तरीके से मिनीडंप को संसाधित करना जारी रखें और देखें कि क्या कोई अन्य प्रदर्शन सुधार किया जाना है।
Bugsnag आपकी एप्लिकेशन स्थिरता में सुधार करते हुए सॉफ़्टवेयर बग्स को प्राथमिकता देने और ठीक करने में आपकी सहायता करता है।